package com.simple.utils;

import java.security.Key;
import java.security.MessageDigest;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.shiro.crypto.hash.SimpleHash;

/**
 * 加解密工具类
 * 
 */
public class EncryptionUtils {

	public final static String KEY = "zne1KSZZOAZ123FG";
	
	

	// 创建Base64对象,用于加密和解密;
	private final static Base64 base64 = new Base64();

	// 加密时采用的编码方式;
	private final static String encoding = "UTF-8";

	/**
	 * 密码加密算法先用MD5进行非对称加密，再用encryptBase64对称加密
	 */
	public static String encryPassword(String strSRc) {
		return encryptBase64(encryptMd5(strSRc),EncryptionUtils.KEY);
	}
	
	
	public static String encryDEDEPassword(String strSRc) {
		return DigestUtils.md5Hex(strSRc);
	}
	

	/**
	 * 基于MD5算法的非对称加密(无解密算法)
	 * 
	 * @param strSrc
	 *            明文
	 * @return 返回密文
	 */
	public static String encryptMd5(String strSrc) {
		StringBuffer sbuffer=new StringBuffer();
		try {
			MessageDigest md5 = MessageDigest.getInstance("MD5");
			byte[] outByte = md5.digest(strSrc.getBytes("UTF-8"));
			
			for (byte b : outByte) {
				int val=((int)b)&0xff;//16
				if(val<16)
					sbuffer.append("0");
				sbuffer.append(Integer.toHexString(val));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sbuffer.toString();
	}

	/**
	 * 用Base64对加密好的byte数组进行编码，返回字符串
	 * 
	 * @param str
	 *            需要加密的字符串
	 * @param sKey
	 *            加密密钥
	 * @return 经过加密的字符串
	 */
	public static String encryptBase64(String str, String sKey) {
		// 声明加密后的结果字符串变量
		String result = str;
		if (str != null && str.length() > 0 && sKey != null
				&& sKey.length() >= 8) {
			try {
				// 调用DES 加密数组的 encrypt方法，返回加密后的byte数组;
				byte[] encodeByte = encryptBasedDes(str.getBytes(encoding),
						sKey);
				// 调用base64的编码方法，返回加密后的字符串;
				result = base64.encodeToString(encodeByte).trim();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return result;
	}
	
	
	

	/**
	 * 用Base64对字符串进行编码，返回byte数组
	 * 
	 * @param str
	 *            需要解密的字符串
	 * @param sKey
	 *            解密密钥
	 * @return 经过解密的字符串
	 */
	public static String decryptBase64(String str, String sKey) {
		String result = str;
		if (str != null && str.length() > 0 && sKey != null
				&& sKey.length() >=4) {
			try {
				// 用base64进行编码，返回byte数组
				byte[] encodeByte = base64.decode(str);
				// 调用DES 解密数组的decrypte方法，返回解密后的数组;
				byte[] decoder = decryptBasedDes(encodeByte, sKey);
				// 对解密后的数组转化成字符串
				result = new String(decoder, encoding).trim();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return result;
	}

	/**
	 * 先用DES算法对byte[]数组加密
	 * 
	 * @param byteSource
	 *            需要加密的数据
	 * @param sKey
	 *            加密密钥
	 * @return 经过加密的数据
	 * @throws Exception
	 */
	private static byte[] encryptBasedDes(byte[] byteSource, String sKey)
			throws Exception {
		try {
			// 声明加密模式;
			int mode = Cipher.ENCRYPT_MODE;
			// 创建密码工厂对象;
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			// 把字符串格式的密钥转成字节数组;
			byte[] keyData = sKey.getBytes();
			// 以密钥数组为参数，创建密码规则
			DESKeySpec keySpec = new DESKeySpec(keyData);
			// 以密码规则为参数，用密码工厂生成密码
			Key key = keyFactory.generateSecret(keySpec);
			// 创建密码对象
			Cipher cipher = Cipher.getInstance("DES");
			// 以加密模式和密码为参数对密码对象 进行初始化
			cipher.init(mode, key);
			// 完成最终加密
			byte[] result = cipher.doFinal(byteSource);
			// 返回加密后的数组
			return result;
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 先用DES算法对byte[]数组解密
	 * 
	 * @param byteSource
	 *            需要解密的数据
	 * @param sKey
	 *            解密密钥
	 * @return 经过解密的数据
	 * @throws Exception
	 */
	private static byte[] decryptBasedDes(byte[] byteSource, String sKey)
			throws Exception {
		try {
			// 声明解密模式;
			int mode = Cipher.DECRYPT_MODE;
			// 创建密码工厂对象;
			SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
			// 把字符串格式的密钥转成字节数组;
			byte[] keyData = sKey.getBytes();
			// 以密钥数组为参数，创建密码规则
			DESKeySpec keySpec = new DESKeySpec(keyData);
			// 以密码规则为参数，用密码工厂生成密码
			Key key = keyFactory.generateSecret(keySpec);
			// 创建密码对象
			Cipher cipher = Cipher.getInstance("DES");
			// 以加密模式和密码为参数对密码对象 进行初始化
			cipher.init(mode, key);
			// 完成最终解密
			byte[] result = cipher.doFinal(byteSource);
			// 返回解密后的数组
			return result;
		} catch (Exception e) {
			throw e;
		}
	}
	
	/**
	 * shiro  MD5加密
	 * 
	 * 
	 * */
	public static String shiroMd5(String character) {
		String hashAlgorithmName = "MD5";//加密方式
		Object salt = null;//盐值
		int hashIterations = 1024;//加密一次
		SimpleHash result = new SimpleHash(hashAlgorithmName,character,salt,hashIterations);
		return result.toString();
		
	}
	

	/**
	 * 测试对称加密算法
	 * 
	 * @param args
	 * @throws IOException
	 */
//	public static void main(String[] args) throws IOException {
//		String mail="1570868334@qq.com";
//		String key="noteTest";
//		String time=EncryptionUtils.encryptBase64(mail, key);
//		System.out.println(time);
//		String encriotionMail=EncryptionUtils.encryptBase64("1570868334@qq.com","noteTest");
//		
//		
//		System.out.println("encriotionMail="+encriotionMail);
//		//System.out.println(decryptBase64("TFNQslxC+pf76/3lRCkiqQ==",key));
//		System.out.println(shiroMd5("admin"));//0cb506c8c95a66e87c463bf1a270446c   1024次 21232f297a57a5a743894a0e4a801fc3  1次
//
//	}

}
